// HTMLParser Library $Name: v1_6 $ - A java-based parser for HTML
// http://sourceforge.org/projects/htmlparser
// Copyright (C) 2004 Derrick Oswald
//
// Revision Control Information
//
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/nodes/TextNode.java,v $
// $Author: derrickoswald $
// $Date: 2006/05/31 02:10:15 $
// $Revision: 1.6 $
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

package org.htmlparser.nodes;

import org.htmlparser.Text;
import org.htmlparser.lexer.Cursor;
import org.htmlparser.lexer.Page;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.NodeVisitor;

/**
 * Normal text in the HTML document is represented by this class.
 */
public class TextNode extends AbstractNode implements Text {
	/**
	 * The contents of the string node, or override text.
	 */
	protected String mText;

	/**
	 * Constructor takes in the text string.
	 * 
	 * @param text
	 *            The string node text. For correct generation of HTML, this
	 *            should not contain representations of tags (unless they are
	 *            balanced).
	 */
	public TextNode(String text) {
		super(null, 0, 0);
		setText(text);
	}

	/**
	 * Constructor takes in the page and beginning and ending posns.
	 * 
	 * @param page
	 *            The page this string is on.
	 * @param start
	 *            The beginning position of the string.
	 * @param end
	 *            The ending positiong of the string.
	 */
	public TextNode(Page page, int start, int end) {
		super(page, start, end);
		mText = null;
	}

	/**
	 * Returns the text of the node. This is the same as {@link #toHtml} for
	 * this type of node.
	 * 
	 * @return The contents of this text node.
	 */
	public String getText() {
		return (toHtml());
	}

	/**
	 * Sets the string contents of the node.
	 * 
	 * @param text
	 *            The new text for the node.
	 */
	public void setText(String text) {
		mText = text;
		nodeBegin = 0;
		nodeEnd = mText.length();
	}

	/**
	 * Returns the text of the node. This is the same as {@link #toHtml} for
	 * this type of node.
	 * 
	 * @return The contents of this text node.
	 */
	public String toPlainTextString() {
		return (toHtml());
	}

	/**
	 * Returns the text of the node.
	 * 
	 * @param verbatim
	 *            If <code>true</code> return as close to the original page
	 *            text as possible.
	 * @return The contents of this text node.
	 */
	public String toHtml(boolean verbatim) {
		String ret;

		ret = mText;
		if (null == ret)
			ret = mPage.getText(getStartPosition(), getEndPosition());

		return (ret);
	}

	/**
	 * Express this string node as a printable string This is suitable for
	 * display in a debugger or output to a printout. Control characters are
	 * replaced by their equivalent escape sequence and contents is truncated to
	 * 80 characters.
	 * 
	 * @return A string representation of the string node.
	 */
	public String toString() {
		int startpos;
		int endpos;
		Cursor start;
		Cursor end;
		char c;
		StringBuffer ret;

		startpos = getStartPosition();
		endpos = getEndPosition();
		ret = new StringBuffer(endpos - startpos + 20);
		if (null == mText) {
			start = new Cursor(getPage(), startpos);
			end = new Cursor(getPage(), endpos);
			ret.append("Txt (");
			ret.append(start);
			ret.append(",");
			ret.append(end);
			ret.append("): ");
			while (start.getPosition() < endpos) {
				try {
					c = mPage.getCharacter(start);
					switch (c) {
					case '\t':
						ret.append("\\t");
						break;
					case '\n':
						ret.append("\\n");
						break;
					case '\r':
						ret.append("\\r");
						break;
					default:
						ret.append(c);
					}
				} catch (ParserException pe) {
					// not really expected, but we're only doing toString, so
					// ignore
				}
				if (77 <= ret.length()) {
					ret.append("...");
					break;
				}
			}
		} else {
			ret.append("Txt (");
			ret.append(startpos);
			ret.append(",");
			ret.append(endpos);
			ret.append("): ");
			for (int i = 0; i < mText.length(); i++) {
				c = mText.charAt(i);
				switch (c) {
				case '\t':
					ret.append("\\t");
					break;
				case '\n':
					ret.append("\\n");
					break;
				case '\r':
					ret.append("\\r");
					break;
				default:
					ret.append(c);
				}
				if (77 <= ret.length()) {
					ret.append("...");
					break;
				}
			}
		}

		return (ret.toString());
	}

	/**
	 * Returns if the node consists of only white space. White space can be
	 * spaces, new lines, etc.
	 */
	public boolean isWhiteSpace() {
		if (mText == null || mText.trim().equals(""))
			return true;
		return false;
	}

	/**
	 * String visiting code.
	 * 
	 * @param visitor
	 *            The <code>NodeVisitor</code> object to invoke
	 *            <code>visitStringNode()</code> on.
	 */
	public void accept(NodeVisitor visitor) {
		visitor.visitStringNode(this);
	}
}
